package com.ruoyi.salesInvoice.service.impl;

import com.ruoyi.audit.domain.Audit;
import com.ruoyi.audit.mapper.AuditMapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.WXShiroUtils;
import com.ruoyi.expressdelivery.mapper.ExpreeDeliveryMapper;
import com.ruoyi.sale.domain.SaleGoodsModel;
import com.ruoyi.sale.mapper.SaleGoodsMapper;
import com.ruoyi.salesInvoice.domain.SalesInvoiceModel;
import com.ruoyi.salesInvoice.domain.SalesInvoiceOrder;
import com.ruoyi.salesInvoice.invoiceStatusMachine.InvoiceService;
import com.ruoyi.salesInvoice.invoiceStatusMachine.InvoiceServiceFactory;
import com.ruoyi.salesInvoice.mapper.SalesInvoiceMapper;
import com.ruoyi.salesInvoice.service.SalesInvoiceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static java.util.stream.Collectors.toList;

@Service
public class SalesInvoiceServiceImpl implements SalesInvoiceService {

    @Autowired
    private SalesInvoiceMapper salesInvoiceMapper;

    @Autowired
    private AuditMapper auditMapper;

    @Autowired
    private SaleGoodsMapper saleGoodsMapper;

    /**
     * 查询销售发票订单列表
     *
     * @param salesInvoiceOrder 查询条件
     * @return 结果
     */
    @Override
    public List<SalesInvoiceOrder> selectSalesInvoice(SalesInvoiceOrder salesInvoiceOrder) {
        return salesInvoiceMapper.selectSalesInvoice(salesInvoiceOrder);
    }


    /**
     * 插入销售发票信息
     *
     * @param salesInvoiceOrder 插入数据
     * @return 结果
     */
    @Override
    @Transactional
    public int insertSalesInvoiceOrder(SalesInvoiceOrder salesInvoiceOrder) {

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        salesInvoiceOrder.setDeptId(sysUser.getCompanyId());
        salesInvoiceOrder.setCreateBy(sysUser.getNickName());


        salesInvoiceOrder.setCompanyId(salesInvoiceOrder.getCustomerId());
        int i = salesInvoiceMapper.insertSalesInvoiceOrder(salesInvoiceOrder);
        if (salesInvoiceOrder.getSalesInvoiceModelList() != null) {
            salesInvoiceMapper.insertSalesInvoiceModelByOrder(salesInvoiceOrder);
        }

        //添加审核订单
        Audit audit = new Audit();
        audit.setOrderId(salesInvoiceOrder.getSalesInvoiceId());
        audit.setCompanyId(sysUser.getCompanyId());
        audit.setOrderType("7");
        audit.setAuditStatus("0");
        audit.setUserId(salesInvoiceOrder.getUserId());
        audit.setSupplierId(salesInvoiceOrder.getCompanyId());
        audit.setTaxAmount(salesInvoiceOrder.getTaxTotalAmount());
        //订单编号
        audit.setOrderNum(salesInvoiceOrder.getSalesInvoiceNum());
        auditMapper.insertAudit(audit);

        countSalesGoods(salesInvoiceOrder.getSalesInvoiceId());
//        throw new RuntimeException("");
        return i;
    }

    /**
     * 查询销售订单信息
     *
     * @param salesInvoiceId 查询条件
     * @return 结果
     */
    @Override
    public SalesInvoiceOrder selectSalesInvoiceOrderById(Long salesInvoiceId) {
        return salesInvoiceMapper.selectSalesInvoiceOrderById(salesInvoiceId);
    }

    /**
     * 修改销售发票信息
     *
     * @param salesInvoiceOrder 修改数据
     * @return 结果
     */
    @Override
    @Transactional
    public int updateSalesInvoiceOrder(SalesInvoiceOrder salesInvoiceOrder) {
        int i = salesInvoiceMapper.updateSalesInvoiceOrder(salesInvoiceOrder);
        //当前销售发票子集数据
        List<SalesInvoiceModel> salesInvoiceModelList = salesInvoiceOrder.getSalesInvoiceModelList();
        //查询出来的销售发票子集数据
        List<SalesInvoiceModel> salesInvoiceModels = salesInvoiceMapper.selectSalesInvoiceModelByOrderId(salesInvoiceOrder.getSalesInvoiceId());
        List<Long> salesInvoiceNoList = new ArrayList<>();
        //定义新的销售发票的子表主键，用于计算修改销货单数量
        List<Long> longs = new ArrayList<>();

        if (salesInvoiceModelList == null) {
            for (SalesInvoiceModel salesInvoiceModel : salesInvoiceModels) {
                salesInvoiceNoList.add(salesInvoiceModel.getSalesInvoiceNo());
            }
        } else {
            for (int i1 = 0; i1 < salesInvoiceModelList.size(); i1++) {
                if (salesInvoiceModels.size() != 0) {
                    for (int j = salesInvoiceModels.size() - 1; j >= 0; j--) {
                        if (salesInvoiceModelList.get(i1).getSalesInvoiceNo().equals(salesInvoiceModels.get(j).getSalesInvoiceNo())) {
                            salesInvoiceModels.remove(j);
                            continue;
                        }
                        longs.add(salesInvoiceModels.get(j).getSalesInvoiceNo());
                    }
                }
            }
            for (int i1 = 0; i1 < salesInvoiceModels.size(); i1++) {
                salesInvoiceNoList.add(salesInvoiceModels.get(i1).getSalesInvoiceNo());
            }
        }
        salesInvoiceMapper.updateSalesInvoiceModelList(salesInvoiceModelList);
        if (salesInvoiceNoList.size() != 0) {
            //计算销售发票中的剩余数量
            countSalesGoodsId(salesInvoiceNoList);
            //删除销售发票中的子表信息
            salesInvoiceMapper.deleteSalesInvoiceModelList(salesInvoiceNoList);
        }
        countSalesGoodsEdit(salesInvoiceModelList);
//        throw new RuntimeException("错误测试");*-
        return i;
    }

    /**
     * 删除销售发票信息
     *
     * @param salesInvoiceId 销售发票id集合
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteSalesInvoiceOrderById(Long salesInvoiceId) {
        List<SalesInvoiceModel> salesInvoiceModels = salesInvoiceMapper.selectSalesInvoiceModelByOrderId(salesInvoiceId);
        List<Long> salesInvoiceNoList = new ArrayList<>();
        for (SalesInvoiceModel salesInvoiceModel : salesInvoiceModels) {
            salesInvoiceNoList.add(salesInvoiceModel.getSalesInvoiceNo());
        }

        Audit audit = new Audit();
        audit.setOrderId(salesInvoiceId);
        audit.setOrderType("7");
        audit = auditMapper.selectAuditByOrderId(audit);
        auditMapper.deleteAuditById(audit.getAuditId());
        SalesInvoiceOrder salesInvoiceOrder = salesInvoiceMapper.selectSalesInvoiceOrderById(salesInvoiceId);

        //判断销售发票是否是已驳回，是则不进行计算剩余数量
        if (salesInvoiceOrder.getInvoiceStatus().equals("0")) {
            //计算销售发票中的剩余数量
            countSalesGoodsId(salesInvoiceNoList);
        }
        salesInvoiceMapper.deleteSalesInvoiceModelList(salesInvoiceNoList);
        return salesInvoiceMapper.deleteSalesInvoiceOrderById(salesInvoiceId);
    }

    /**
     * 计算销售发票信息
     *
     * @param salesInvoiceId 销售发票id
     * @return 结果
     */
    @Override
    @Transactional
    public int countSalesGoods(Long salesInvoiceId) {
        //通过销售发票主键查询销售发票子表的数据
        List<SalesInvoiceModel> salesInvoiceModels = salesInvoiceMapper.selectSalesInvoiceModelByOrderId(salesInvoiceId);
        //新的数据集合，用于存储需要删除的数据
        ArrayList<Long> longs = new ArrayList<>();
        for (SalesInvoiceModel salesInvoiceModel : salesInvoiceModels) {
            longs.add(salesInvoiceModel.getSaleGoodsModelId());
        }
        List<SaleGoodsModel> saleGoodsModels = saleGoodsMapper.selectSaleGoodsModelByLists(longs);
        List<SaleGoodsModel> saleGoodsModelList = new ArrayList<SaleGoodsModel>();
        for (int i = 0; i < salesInvoiceModels.size(); i++) {
            //销售发票中销售子表信息
            SalesInvoiceModel salesInvoiceModel = salesInvoiceModels.get(i);
            //销售发票中销货单子表主键,销售发票开票数量
            Long saleGoodsModelId = salesInvoiceModel.getSaleGoodsModelId();
            int salesInvoiceModelNum = salesInvoiceModel.getAllNum().intValue();
            for (int j = saleGoodsModels.size() - 1; j >= 0; j--) {
                //销货单子表信息
                SaleGoodsModel saleGoodsModel = saleGoodsModels.get(j);
                //销货单子表中的销货单子表主键
                Long saleGoodsModelId1 = saleGoodsModel.getSaleGoodsModelId();
                //执行数量
                int executeNum = saleGoodsModel.getExecuteNum();

                //执行状态
                String executeStatus = saleGoodsModel.getExecuteStatus();

                //剩余数量
                int remainingNum = saleGoodsModel.getRemainingNum();
                //销货单数量
                int saleGoodsModelsNum = saleGoodsModel.getNum();

                if (saleGoodsModelId.equals(saleGoodsModelId1)) {
                    remainingNum -= salesInvoiceModelNum;
                    if (remainingNum == 0) {
                        executeStatus = "1";
                    } else if (remainingNum == saleGoodsModelsNum) {
                        executeStatus = "0";
                    } else {
                        executeStatus = "2";
                    }
                    executeNum += salesInvoiceModelNum;
                    saleGoodsModel.setRemainingNum(remainingNum);
                    saleGoodsModel.setExecuteNum(executeNum);
                    saleGoodsModel.setExecuteStatus(executeStatus);

                    saleGoodsModelList.add(saleGoodsModel);
                }
            }
        }
        return saleGoodsMapper.updateSaleGoodsModelList(saleGoodsModelList);
    }

    /**
     * 计算销售发票信息
     *
     * @param salesInvoiceId 销售发票id
     * @return 结果
     */
    @Override
    @Transactional
    public int countReturnSalesGoods(Long salesInvoiceId) {
        List<SalesInvoiceModel> salesInvoiceModels = salesInvoiceMapper.selectSalesInvoiceModelByOrderId(salesInvoiceId);
        ArrayList<Long> longs = new ArrayList<>();
        for (SalesInvoiceModel salesInvoiceModel : salesInvoiceModels) {
            longs.add(salesInvoiceModel.getSaleGoodsModelId());
        }
        List<SaleGoodsModel> saleGoodsModels = saleGoodsMapper.selectSaleGoodsModelByLists(longs);
        List<SaleGoodsModel> saleGoodsModelList = new ArrayList<SaleGoodsModel>();
        for (int i = 0; i < salesInvoiceModels.size(); i++) {
            //销售发票中销售子表信息
            SalesInvoiceModel salesInvoiceModel = salesInvoiceModels.get(i);
            //销售发票中销货单子表主键,销售发票开票数量
            Long saleGoodsModelId = salesInvoiceModel.getSaleGoodsModelId();
            int salesInvoiceModelNum = salesInvoiceModel.getAllNum().intValue();
            for (int j = saleGoodsModels.size() - 1; j >= 0; j--) {
                //销货单子表信息
                SaleGoodsModel saleGoodsModel = saleGoodsModels.get(j);
                //销货单子表中的销货单子表主键
                Long saleGoodsModelId1 = saleGoodsModel.getSaleGoodsModelId();
                //执行数量
                int executeNum = saleGoodsModel.getExecuteNum();

                //执行状态
                String executeStatus = saleGoodsModel.getExecuteStatus();

                //剩余数量
                int remainingNum = saleGoodsModel.getRemainingNum();
                //销货单数量
                int saleGoodsModelsNum = saleGoodsModel.getNum();

                if (saleGoodsModelId.equals(saleGoodsModelId1)) {
                    remainingNum += salesInvoiceModelNum;
                    if (remainingNum == 0) {
                        executeStatus = "1";
                    } else if (remainingNum == saleGoodsModelsNum) {
                        executeStatus = "0";
                    } else {
                        executeStatus = "2";
                    }
                    executeNum -= salesInvoiceModelNum;
                    saleGoodsModel.setRemainingNum(remainingNum);
                    saleGoodsModel.setExecuteNum(executeNum);
                    saleGoodsModel.setExecuteStatus(executeStatus);

                    saleGoodsModelList.add(saleGoodsModel);
                }
            }
        }
        return saleGoodsMapper.updateSaleGoodsModelList(saleGoodsModelList);
    }

    /**
     * 计算修改销售发票中删除的销售发票信息
     *
     * @param aLong 删除的销发票集合
     * @return 结果
     */
    @Transactional
    int countSalesGoodsId(List<Long> aLong) {

        List<SalesInvoiceModel> salesInvoiceModels = salesInvoiceMapper.selectSalesInvoiceModelByModelsIdList(aLong);
        ArrayList<Long> longs = new ArrayList<>();
        for (SalesInvoiceModel salesInvoiceModel : salesInvoiceModels) {
            longs.add(salesInvoiceModel.getSaleGoodsModelId());
        }
        List<SaleGoodsModel> saleGoodsModels = saleGoodsMapper.selectSaleGoodsModelByLists(longs);
        List<SaleGoodsModel> saleGoodsModelList = new ArrayList<SaleGoodsModel>();
        for (int i = 0; i < salesInvoiceModels.size(); i++) {
            //销售发票中销售子表信息
            SalesInvoiceModel salesInvoiceModel = salesInvoiceModels.get(i);
            //销售发票中销货单子表主键,销售发票开票数量
            Long saleGoodsModelId = salesInvoiceModel.getSaleGoodsModelId();
            int salesInvoiceModelNum = salesInvoiceModel.getAllNum().intValue();
            for (int j = saleGoodsModels.size() - 1; j >= 0; j--) {
                //销货单子表信息
                SaleGoodsModel saleGoodsModel = saleGoodsModels.get(j);
                //销货单子表中的销货单子表主键
                Long saleGoodsModelId1 = saleGoodsModel.getSaleGoodsModelId();
                //执行数量
                int executeNum = saleGoodsModel.getExecuteNum();
                //执行状态
                String executeStatus = saleGoodsModel.getExecuteStatus();
                //剩余数量
                int remainingNum = saleGoodsModel.getRemainingNum();
                //销货单数量
                int saleGoodsModelsNum = saleGoodsModel.getAllNum();

                if (saleGoodsModelId.equals(saleGoodsModelId1)) {
                    remainingNum += salesInvoiceModelNum;
                    if (remainingNum == 0) {
                        executeStatus = "1";
                    } else if (remainingNum == saleGoodsModelsNum) {
                        executeStatus = "0";
                    } else {
                        executeStatus = "2";
                    }
                    executeNum -= salesInvoiceModelNum;
                    saleGoodsModel.setRemainingNum(remainingNum);
                    saleGoodsModel.setExecuteNum(executeNum);
                    saleGoodsModel.setExecuteStatus(executeStatus);
                    saleGoodsModelList.add(saleGoodsModel);
                }
            }
        }
        return saleGoodsMapper.updateSaleGoodsModelList(saleGoodsModelList);
    }

    /**
     * 计算修改销售发票中修改的销售发票信息
     *
     * @param salesInvoiceModels 销售发票需要修改的子表数据
     * @return 结果
     */
//    @Override
    @Transactional
    int countSalesGoodsEdit(List<SalesInvoiceModel> salesInvoiceModels) {
        ArrayList<Long> longs = new ArrayList<>();
        for (SalesInvoiceModel salesInvoiceModel : salesInvoiceModels) {
            longs.add(salesInvoiceModel.getSaleGoodsModelId());
        }
        List<SaleGoodsModel> saleGoodsModels = saleGoodsMapper.selectSaleGoodsModelByLists(longs);
        List<SaleGoodsModel> saleGoodsModelList = new ArrayList<SaleGoodsModel>();
        for (int i = 0; i < salesInvoiceModels.size(); i++) {
            //销售发票中销售子表信息
            SalesInvoiceModel salesInvoiceModel = salesInvoiceModels.get(i);
            //销售发票中销货单子表主键,销售发票开票数量
            Long saleGoodsModelId = salesInvoiceModel.getSaleGoodsModelId();
            int salesInvoiceModelNum = salesInvoiceModel.getAllNum().intValue();
            int remainingNum = salesInvoiceModel.getRemainingNums();
            for (int j = saleGoodsModels.size() - 1; j >= 0; j--) {
                //销货单子表信息
                SaleGoodsModel saleGoodsModel = saleGoodsModels.get(j);
                //销货单子表中的销货单子表主键
                Long saleGoodsModelId1 = saleGoodsModel.getSaleGoodsModelId();
                //执行数量
                //执行状态
                String executeStatus = saleGoodsModel.getExecuteStatus();
                //剩余数量
                //销货单数量
                int saleGoodsModelsNum = saleGoodsModel.getAllNum();
                if (saleGoodsModelId.equals(saleGoodsModelId1)) {
                    int remainingNum1 = saleGoodsModel.getAllNum() - salesInvoiceModelNum;
                    if (remainingNum1 == 0) {
                        executeStatus = "1";
                    } else if (remainingNum1 == saleGoodsModelsNum) {
                        executeStatus = "0";
                    } else if (remainingNum1 < 0) {
                        throw new RuntimeException("第" + (i + 1) + "输入的数量超过当前销货单的数量，请重新输入！");
                    } else {
                        executeStatus = "2";
                    }
                    saleGoodsModel.setRemainingNum(saleGoodsModel.getAllNum() - salesInvoiceModelNum);
                    saleGoodsModel.setExecuteNum(salesInvoiceModelNum);
                    saleGoodsModel.setExecuteStatus(executeStatus);

                    saleGoodsModelList.add(saleGoodsModel);
                }
            }
        }
        return saleGoodsMapper.updateSaleGoodsModelList(saleGoodsModelList);
    }

    /**
     * 查询销售发票子表数据信息
     *
     * @param salesInvoiceNo 销售发票子表
     * @return 结果
     */
    @Override
    public SalesInvoiceModel selectSalesInvoiceModelById(Long salesInvoiceNo) {
        return salesInvoiceMapper.selectSalesInvoiceModelById(salesInvoiceNo);
    }

    /**
     * 查询销售发票子集数据
     *
     * @param salesInvoiceModel 查询条件
     * @return 结果
     */
    @Override
    public SalesInvoiceModel selectInvoiceByIds(SalesInvoiceModel salesInvoiceModel) {
        return salesInvoiceMapper.selectInvoiceByIds(salesInvoiceModel);
    }

    /**
     * 通过销售发票主键 查询销售发票子集数据集合
     *
     * @param salesInvoiceId 销售发票主键
     * @return 结果
     */
    @Override
    public List<SalesInvoiceModel> selectSalesInvoiceModelByOrderId(Long salesInvoiceId) {
        return salesInvoiceMapper.selectSalesInvoiceModelByOrderId(salesInvoiceId);
    }

    /**
     * 计算销售发票中销货单是否全部生成销售发票
     *
     * @param salesInvoiceId 销售发票主键
     * @return 结果
     */
    @Override
    public int countIsInvoice(Long salesInvoiceId) {
        SalesInvoiceOrder salesInvoiceOrder = salesInvoiceMapper.selectSalesInvoiceOrderById(salesInvoiceId);
        List<SalesInvoiceModel> salesInvoiceModelList = salesInvoiceOrder.getSalesInvoiceModelList();
        List<Long> saleGoodsModelIdList = new ArrayList<>();
        if (salesInvoiceModelList.size() != 0) {
            for (SalesInvoiceModel salesInvoiceModel : salesInvoiceModelList) {
                Long saleGoodsModelId = salesInvoiceModel.getSaleGoodsModelId();
                saleGoodsModelIdList.add(saleGoodsModelId);
            }
        }

        List<SaleGoodsModel> saleGoodsModels = saleGoodsMapper.selectSaleGoodsModelByModelIdList(saleGoodsModelIdList);
        Map<Long, Long> map = new HashMap<>();
        List<Long> saleGoodsIdList = new ArrayList<>();

        if (saleGoodsModels.size() != 0) {
            for (SaleGoodsModel saleGoodsModel : saleGoodsModels) {
                Long saleGoodsId = saleGoodsModel.getSaleGoodsId();
                map.put(saleGoodsId, saleGoodsId);
                saleGoodsIdList.add(saleGoodsId);
            }
        }

        //获取新的list集合，去重
        List<Long> listNew = new ArrayList<Long>(new TreeSet<Long>(saleGoodsIdList));

        //判断是否有销货单的开票信息不为0的销货单
        List<Long> saleGoodsList = saleGoodsMapper.selectSaleGoodsIdByList(listNew);
        //去除不为0的数据
        List<Long> reduce1 = listNew.stream().filter(item -> !saleGoodsList.contains(item)).collect(toList());

//        listNew.removeAll(saleGoodsList);

        if (reduce1.size() != 0) {
            int i = saleGoodsMapper.updateSaleorderOrderIsPays(reduce1);
        }
        return 0;
    }

    /**
     * 发票审核状态机
     */
    private InvoiceServiceFactory invoiceServiceFactory;
    public SalesInvoiceServiceImpl(InvoiceServiceFactory invoiceServiceFactory) {
        this.invoiceServiceFactory = invoiceServiceFactory;
    }

    /**
     * 发票状态流转
     * @param salesInvoiceOrder
     * @return
     */
    @Override
    public int auditSale(SalesInvoiceOrder salesInvoiceOrder) {
        InvoiceService query = invoiceServiceFactory.query(salesInvoiceOrder.getInvoiceStatus());
        int execute = query.execute(salesInvoiceOrder);
        return execute;
    }


    @Override
    public Long querypreviousId(Long salesInvoiceId) {
        Map<String, Object> params = new HashMap<>();
        params.put("salesInvoiceId", salesInvoiceId);
        params.put("deptId", SecurityUtils.getDeptId());
        return salesInvoiceMapper.querypreviousId(params);
    }

    @Override
    public Long queryNextId(Long salesInvoiceId) {
        Map<String, Object> params = new HashMap<>();
        params.put("salesInvoiceId", salesInvoiceId);
        params.put("deptId", SecurityUtils.getDeptId());
        return salesInvoiceMapper.queryNextId(params);
    }

    @Override
    public List<Map<String, Object>> pendingReview(Long deptID) {
        return salesInvoiceMapper.pendingReview(deptID)
                .stream()
                .peek(item -> item.put("orderType", "销售发票"))
                .collect(toList());
    }
}
